
class RenderContext(object):
    pass


class Renderer(dict):
    def __init__(self, **initial):
        dict.__init__(self, **initial)
        self.cache = {}
        self.all_dirty = False
    
    def render(self, control):
        self._render(control)
        self.all_dirty = False

    def _render(self, control):
        controlname = control.__class__.__name__
        if control._computed_style is None or control._dirty or self.all_dirty: 
            control.dispatch_event("on_compute_style")

        if control._computed_style['display']:
            try:
                render_func = self.cache[controlname]
            except KeyError:
                try:
                    render_func = self[controlname]
                except KeyError:
                    render_func = self.cache[controlname] = \
                        self._find_renderer(control.__class__.__bases__)

            if render_func:
                try:
                    context = control._render_context
                except AttributeError:
                    context = control._render_context = RenderContext()
                render_func(control, context)
            else:
                print "no renderfunc!", control, self.keys()

        control._dirty = False

        self.render_children(control)

    def render_children(self, control):
        for child in control._children:
            self._render(child)

    def _find_renderer(self, bases):
        for base in bases:
            base_name = base.__name__
            if self.has_key(base_name):
                return self[base_name]            
            if base.__bases__:
                r = self._find_renderer(base.__bases__)
                if r: 
                    return r




